package com.bluesky.jwf.component;

import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

import com.bluesky.common.TreeNode;
import com.bluesky.javawebbrowser.domain.html.HtmlPage;
import com.bluesky.javawebbrowser.domain.html.tags.Tag;
import com.bluesky.javawebbrowser.domain.html.tags.TagType;
import com.bluesky.javawebbrowser.domain.html.tags.Title;
import com.bluesky.jwf.ComponentFactory;
import com.bluesky.jwf.component.window.Window;

/**
 * a HTML page, wrap its content with a html form tag.
 * 
 * @author hz00260
 * 
 */
public class Page extends Component {

	private String uri;

	private Title titleTag;
	private Tag htmlTag;
	private Tag bodyTag;
	private Form form;
	/**
	 * current window object
	 */
	private Window window;

	@Override
	public void init(String html) {
		HtmlPage page = new HtmlPage(html, true);

		Tag rootTag = page.getRoot();

		for (TreeNode tn : rootTag.getChildren())
			addChild(tn);

		titleTag = (Title) loadByTagType(TagType.TITLE);
		htmlTag = loadByTagType(TagType.HTML);

		bodyTag = loadByTagType(TagType.BODY);

		// clear body
		bodyTag.removeAllChildren();

		form = (Form) ComponentFactory.getInstance().createComponent("Form");
		bodyTag.addChild(form);

	}

	public void setWindow(Window window) {
		if (this.window != null)
			form.removeChild(this.window);

		this.window = window;
		titleTag.setTitle(window.getTitle());
		form.getFormTag().addChild(window.getRootWindow());

		// form.getFormTag().setAttribute("action",
		// window.getClass().getSimpleName() + ".jwf");
		form.getFormTag().setAttribute("action", uri);

	}

	public Window getWindow() {
		return this.window;
	}

	

	/**
	 * how to render window with dialog?
	 * 
	 * @param writer
	 */
	public void render(Writer writer) {		

		final List<Tag> scripts = new ArrayList<Tag>();
		// gather scripts
		traverse(new TagProcessor() {
			@Override
			public boolean process(Tag tag) {
				if (tag instanceof Component) {
					Component comp = (Component) tag;
					if (comp.getScript() != null)
						scripts.add(comp.getScript());
				}

				return false;
			}
		});

		/**
		 * process scripts, clear old, add new
		 */
		List<Tag> oldScripts = bodyTag.find(TagType.SCRIPT, false);
		for (Tag tag : oldScripts)
			bodyTag.removeChild(tag);

		for (Tag tag : scripts)
			bodyTag.addChild(tag);

		try {
			writeHtml(writer);
		} catch (Exception e) {
			throw new RuntimeException("write fail:" + e);
		}
	}

	public Tag getHtmlTag() {
		return htmlTag;
	}

	public void setHtmlTag(Tag htmlTag) {
		this.htmlTag = htmlTag;
	}

	public Tag getBodyTag() {
		return bodyTag;
	}

	public void setBodyTag(Tag bodyTag) {
		this.bodyTag = bodyTag;
	}

	public Form getForm() {
		return form;
	}

	public void setFormTag(Form form) {
		this.form = form;
	}

	public String getUri() {
		return uri;
	}

	public void setUri(String uri) {
		this.uri = uri;
	}

}
